#include<iostream>
#include<vector>
#include<queue>
#include<pthread.h>

namespace Blockqueue
{

template<class T>
class blockqueue
{
private:
    bool IsFull(){
        return _queue.size() == 5?true:false;
    }
    bool IsEmpty(){
        return _queue.size() == 0?true:false;
    }
public:
    blockqueue(int cap)
        :_cap(cap)
    {
        pthread_mutex_init(&_mutex,NULL);
    }
    ~blockqueue(){
        pthread_mutex_destroy(&_mutex);
    }

    void product(const T in)
    {
        pthread_mutex_lock(&_mutex);

        while(IsFull())//增加代码的健壮性
        {
            ++_wait_producter;
            pthread_cond_wait(&_procond,&_mutex);
            --_wait_producter;
        }
        std::cout<<"product num:"<<in<<std::endl;
        _queue.push(in);

        if(_wait_comsumer > 0)
            pthread_cond_signal(&_comcond);
        pthread_mutex_unlock(&_mutex);
    }

    void comsume(T* out)
    {
        pthread_mutex_lock(&_mutex);
        while(IsEmpty()){
            ++_wait_comsumer;
            pthread_cond_wait(&_comcond,&_mutex);
            --_wait_comsumer;
        }

        *out = _queue.front();
        std::cout<<"consume num: "<<*out<<std::endl;
        _queue.pop();

        if(_wait_producter > 0)
            pthread_cond_signal(&_procond);
        pthread_mutex_unlock(&_mutex);

    }

private:
    int _cap;
    std::queue<T> _queue;
    pthread_mutex_t _mutex;
    pthread_cond_t _comcond = PTHREAD_COND_INITIALIZER;
    pthread_cond_t _procond = PTHREAD_COND_INITIALIZER;
    int _wait_producter = 0;
    int _wait_comsumer = 0;

};

}